package by.demchenko.sample.webapp.page.admin;

import by.demchenko.sample.datamodel.Person;
import by.demchenko.sample.datamodel.Person_;
import by.demchenko.sample.datamodel.enums.UserType;
import by.demchenko.sample.services.PersonService;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;
import java.util.Iterator;

@AuthorizeInstantiation("ADMIN")
public class StudentsPage extends BaseAdminPage {

    @Inject
    PersonService personService;

    private UserType userType;

    public StudentsPage(UserType userType) {
        this.userType = userType;
    }

    public StudentsPage() {
        this(UserType.STUDENT);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        add(new Label("headerTitle", getPageTitle()));
        add(new Label("subtitle", getString("label." + userType)));

        PersonDataProvider personDataProvider = new PersonDataProvider();

        DataView<Person> dataView = new DataView<Person>("studentsList", personDataProvider) {
            @Override
            protected void populateItem(Item<Person> item) {
                final Person student = item.getModelObject();
                item.add(new Label("name", student.getFullName()));

                Label faculty = new Label("faculty", student.getFaculty() == null ? "" : student.getFaculty().getName());
                item.add(faculty);
                Label dateofbirth = new Label("dateofbirth", student.getDateOfBirth());
                item.add(dateofbirth);
                Label gender = new Label("gender", getString("Gender." + student.getGender()));
                item.add(gender);

                if (userType == UserType.TEACHER) {
                    faculty.setVisible(false);
                    dateofbirth.setVisible(false);
                    gender.setVisible(false);
                }

                item.add(new Label("phone", student.getPhone()));
                item.add(new Label("login", student.getAccount().getLogin()));
                item.add(new Label("email", student.getAccount().getEmail()));

                item.add(new Link("editbutton") {
                    @Override
                    public void onClick() {
                        setResponsePage(new StudentEditPage(student));
                    }
                });
                item.add(new Link("deletebutton") {
                    @Override
                    public void onClick() {
                        personService.delete(student);
                        setResponsePage(new StudentsPage(userType));
                    }
                });
            }
        };

        add(dataView);

        add(new Link("newbutton") {
            @Override
            public void onClick() {
                setResponsePage(new StudentEditPage(new Person()));
            }
        });
    }

    @Override
    public String getVariation() {
        return userType == UserType.STUDENT ? "student" : "teacher";
    }

    private class PersonDataProvider extends SortableDataProvider<Person, SingularAttribute<Person, ?>> {

        public PersonDataProvider() {
            super();
            setSort(Person_.lastName, SortOrder.ASCENDING);
        }

        @Override
        public Iterator<? extends Person> iterator(long l, long l1) {
            SingularAttribute<Person, ?> sortParam = getSort().getProperty();
            SortOrder propertySortOrder = getSortState().getPropertySortOrder(sortParam);
            boolean ascending = SortOrder.ASCENDING.equals(propertySortOrder);
            return personService.getPersonsByType(userType, true).iterator();

        }

        @Override
        public long size() {
            return personService.getCount(UserType.STUDENT);
        }

        @Override
        public IModel<Person> model(Person student) {
            return new CompoundPropertyModel<>(student);
        }
    }

    private IModel<String> getPageTitle() {
        return new Model<String>(getClass().getSimpleName());
    }
}
